import sys
import io
import os

# 修复Windows环境下的编码问题
if sys.platform.startswith('win'):
    # Windows环境下强制设置编码
    import codecs
    sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer)
    sys.stderr = codecs.getwriter('utf-8')(sys.stderr.buffer)
    # 设置环境变量
    os.environ['PYTHONIOENCODING'] = 'utf-8'
else:
    # 非Windows环境使用原有方式
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')

import json
import logging
import subprocess
import soundfile as sf
import numpy as np
import time
import warnings


# 忽略Whisper的FP16警告
warnings.filterwarnings("ignore", message="FP16 is not supported on CPU; using FP32 instead")
warnings.filterwarnings("ignore", category=UserWarning, module="whisper")

def convert_webm_to_wav(webm_path, wav_path):
    """优化的音频转换"""
    cmd = [
        'ffmpeg', '-y', '-i', webm_path,
        '-ar', '16000', '-ac', '1', '-f', 'wav', 
        '-loglevel', 'error',  # 减少日志输出
        '-threads', '1',  # 单线程处理
        wav_path
    ]
    subprocess.run(cmd, check=True, capture_output=True)


def load_model_once():
    """全局模型加载，避免重复加载"""
    global _model_instance
    if '_model_instance' not in globals():
        print("正在加载语音识别模型...", file=sys.stderr)
        try:
            # 使用whisper模型，它更容易使用且效果很好
            import whisper
            
            # 设置环境变量来抑制FP16警告
            os.environ['WHISPER_CPU_FP16_WARNING'] = '0'
            os.environ['CUDA_VISIBLE_DEVICES'] = ''  # 强制使用CPU
            
            # 使用base模型，更快且更稳定
            _model_instance = whisper.load_model("base")
            print("Whisper模型加载完成", file=sys.stderr)
        except ImportError:
            print("错误: 请先安装whisper库: pip install openai-whisper", file=sys.stderr)
            return None
        except Exception as e:
            print(f"模型加载失败: {e}", file=sys.stderr)
            return None
    return _model_instance

if len(sys.argv) < 2:
    print("Usage: python speech_recognize_paraformer.py <audio_path>", file=sys.stderr)
    exit(1)

audio_path = sys.argv[1]

# 判断是否为 webm 格式
ext = os.path.splitext(audio_path)[1].lower()
if ext == '.webm':
    wav_path = audio_path + '.tmp.wav'
    convert_webm_to_wav(audio_path, wav_path)
    audio_path_for_asr = wav_path
else:
    audio_path_for_asr = audio_path

# 使用全局模型实例
model = load_model_once()
if model is None:
    print(json.dumps([{"error": "模型加载失败"}], ensure_ascii=False))
    exit(1)

try:
    # 使用语音识别模型进行识别
    start_time = time.time()
    
    # 读取音频文件
    if os.path.exists(audio_path_for_asr):
        # 使用whisper进行识别，设置参数优化CPU性能
        result = model.transcribe(
            audio_path_for_asr, 
            language="zh",
            fp16=False,  # 强制使用FP32，避免FP16警告
            verbose=False,  # 减少输出
            temperature=0.0,  # 确定性输出
            compression_ratio_threshold=2.4,  # 优化识别质量
            logprob_threshold=-1.0  # 降低阈值提高识别率
        )
    else:
        print(json.dumps([{"error": "音频文件不存在"}], ensure_ascii=False))
        exit(1)
    
    end_time = time.time()
    processing_time = end_time - start_time
    
    # 处理识别结果
    if result and 'text' in result:
        recognized_text = result['text'].strip()
        
        # 添加控制台输出，显示语音识别的文字内容
        print(f"🎤 语音识别完成 - 识别内容: {recognized_text}", file=sys.stderr)
        
        # 输出结果
        if recognized_text:
            print(json.dumps([{"text": recognized_text}], ensure_ascii=False))
        else:
            print(json.dumps([], ensure_ascii=False))
    else:
        print("🎤 语音识别完成 - 未识别到内容", file=sys.stderr)
        print(json.dumps([], ensure_ascii=False))
    
    # 保存处理时间信息到文件
    try:
        with open("whisper_result.txt", "w", encoding="utf-8") as f:
            f.write(f"处理时间: {processing_time:.2f}秒\n")
            f.write(f"音频文件: {audio_path}\n")
            f.write(f"识别结果: {recognized_text}\n")
            f.write(json.dumps(result, ensure_ascii=False, indent=2))
    except Exception as write_error:
        # 如果写入文件失败，不影响主要功能
        print(f"警告: 无法写入结果文件: {write_error}", file=sys.stderr)

except Exception as e:
    print(json.dumps([{"error": f"识别失败: {str(e)}"}], ensure_ascii=False))

finally:
    # 清理临时 wav 文件
    if ext == '.webm' and os.path.exists(wav_path):
        try:
            os.remove(wav_path)
        except:
            pass
